"""题目技巧分析服务"""
from typing import Dict, Any, List, Optional
from app.ai.legalbert_service import get_legalbert_service
from app.core.database import RedisClient
import json
import hashlib


class QuestionTechniqueService:
    """题目技巧分析服务 - 提供做题技巧分析和建议"""
    
    def __init__(self):
        self.legalbert = get_legalbert_service()
        try:
            self.redis = RedisClient.get_client()
        except:
            self.redis = None
    
    async def analyze_question_structure(
        self,
        question_content: str,
        options: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        分析题目结构
        
        Args:
            question_content: 题目内容
            options: 选项列表（可选）
            
        Returns:
            题目结构分析结果
        """
        # 使用Legal-BERT分析题目结构
        bert_analysis = await self.legalbert.analyze_question_structure(question_content)
        
        # 补充选项分析
        option_analysis = None
        if options:
            option_analysis = await self._analyze_options_structure(options)
        
        return {
            "question_type": bert_analysis.get("question_type", "未知"),
            "keywords": bert_analysis.get("keywords", {}),
            "difficulty": bert_analysis.get("difficulty", "medium"),
            "legal_domain": bert_analysis.get("legal_domain", "其他"),
            "has_case": bert_analysis.get("has_case", False),
            "has_provision": bert_analysis.get("has_provision", False),
            "structure": bert_analysis.get("structure", {}),
            "option_analysis": option_analysis,
            "suggestions": self._generate_structure_suggestions(bert_analysis)
        }
    
    async def identify_keywords(self, question_content: str) -> Dict[str, Any]:
        """
        识别关键词
        
        Args:
            question_content: 题目内容
            
        Returns:
            关键词分析结果
        """
        # 使用Legal-BERT提取关键词
        bert_analysis = await self.legalbert.analyze_question_structure(question_content)
        keywords = bert_analysis.get("keywords", {})
        
        # 补充关键词重要性分析
        keyword_importance = {}
        for category, words in keywords.items():
            keyword_importance[category] = {
                "words": words,
                "count": len(words),
                "importance": "high" if len(words) > 0 else "low"
            }
        
        return {
            "keywords": keywords,
            "keyword_importance": keyword_importance,
            "total_keywords": sum(len(words) for words in keywords.values()),
            "analysis": self._analyze_keyword_patterns(keywords)
        }
    
    async def detect_traps(
        self,
        question_content: str,
        options: Optional[List[str]] = None
    ) -> Dict[str, Any]:
        """
        检测题目陷阱
        
        Args:
            question_content: 题目内容
            options: 选项列表（可选）
            
        Returns:
            陷阱检测结果
        """
        # 使用Legal-BERT检测陷阱
        traps = await self.legalbert.detect_question_traps(question_content)
        
        # 分析选项中的陷阱
        option_traps = []
        if options:
            option_traps = await self._detect_option_traps(options)
        
        # 计算陷阱严重程度
        high_severity_count = sum(1 for trap in traps if trap.get("severity") == "high")
        medium_severity_count = sum(1 for trap in traps if trap.get("severity") == "medium")
        
        return {
            "traps": traps,
            "option_traps": option_traps,
            "summary": {
                "total_traps": len(traps) + len(option_traps),
                "high_severity": high_severity_count,
                "medium_severity": medium_severity_count,
                "risk_level": "high" if high_severity_count > 0 else "medium" if medium_severity_count > 0 else "low"
            },
            "prevention_tips": self._generate_prevention_tips(traps, option_traps)
        }
    
    async def analyze_options(
        self,
        question_content: str,
        options: List[str]
    ) -> Dict[str, Any]:
        """
        分析选项
        
        Args:
            question_content: 题目内容
            options: 选项列表
            
        Returns:
            选项分析结果
        """
        if not options or len(options) < 2:
            return {
                "error": "选项数量不足",
                "analysis": {}
            }
        
        # 使用Legal-BERT分析选项相似度
        similarity_analysis = await self.legalbert.analyze_option_similarity(
            question_content,
            options
        )
        
        # 分析选项特征
        option_features = await self._analyze_option_features(options)
        
        # 生成排除建议
        exclusion_suggestions = self._generate_exclusion_suggestions(
            options,
            similarity_analysis,
            option_features
        )
        
        return {
            "similarity_analysis": similarity_analysis,
            "option_features": option_features,
            "exclusion_suggestions": exclusion_suggestions,
            "comparison_strategy": self._suggest_comparison_strategy(
                similarity_analysis,
                option_features
            )
        }
    
    async def suggest_strategy(
        self,
        question_content: str,
        options: List[str],
        question_type: Optional[str] = None
    ) -> Dict[str, Any]:
        """
        建议答题策略
        
        Args:
            question_content: 题目内容
            options: 选项列表
            question_type: 题目类型（可选）
            
        Returns:
            策略建议
        """
        # 分析题目结构
        structure = await self.analyze_question_structure(question_content, options)
        
        # 检测陷阱
        traps = await self.detect_traps(question_content, options)
        
        # 分析选项
        option_analysis = await self.analyze_options(question_content, options)
        
        # 根据题目类型和特征生成策略
        strategy = {
            "overall_strategy": self._determine_overall_strategy(
                structure,
                traps,
                option_analysis
            ),
            "step_by_step": self._generate_step_by_step_strategy(
                structure,
                traps,
                option_analysis
            ),
            "time_management": self._suggest_time_management(
                structure.get("difficulty", "medium"),
                len(options)
            ),
            "common_mistakes": self._identify_common_mistakes(
                structure,
                traps
            )
        }
        
        return strategy
    
    # 辅助方法
    
    async def _analyze_options_structure(self, options: List[str]) -> Dict[str, Any]:
        """分析选项结构"""
        return {
            "option_count": len(options),
            "average_length": sum(len(opt) for opt in options) / len(options) if options else 0,
            "has_negation": any("不" in opt or "非" in opt for opt in options),
            "has_absolute": any(word in opt for opt in options for word in ["必须", "一定", "绝对"]),
            "structure_type": "uniform" if all(len(opt) < 50 for opt in options) else "mixed"
        }
    
    def _generate_structure_suggestions(self, analysis: Dict[str, Any]) -> List[str]:
        """生成结构分析建议"""
        suggestions = []
        
        if analysis.get("has_case"):
            suggestions.append("这是一道案例题，需要仔细分析案例事实")
        
        if analysis.get("has_provision"):
            suggestions.append("题目涉及法律条文，需要准确理解法条含义")
        
        if analysis.get("question_type") == "综合题":
            suggestions.append("这是综合题，可能涉及多个法律领域，需要全面分析")
        
        difficulty = analysis.get("difficulty", "medium")
        if difficulty == "hard":
            suggestions.append("题目难度较高，建议仔细审题，逐步分析")
        
        return suggestions
    
    def _analyze_keyword_patterns(self, keywords: Dict[str, List[str]]) -> str:
        """分析关键词模式"""
        total = sum(len(words) for words in keywords.values())
        if total == 0:
            return "未检测到明显的关键词"
        
        patterns = []
        if keywords.get("时间词"):
            patterns.append("涉及时间概念")
        if keywords.get("主体词"):
            patterns.append("涉及多个主体")
        if keywords.get("行为词"):
            patterns.append("涉及法律行为")
        if keywords.get("结果词"):
            patterns.append("涉及法律后果")
        
        return "；".join(patterns) if patterns else "关键词模式不明显"
    
    async def _detect_option_traps(self, options: List[str]) -> List[Dict[str, Any]]:
        """检测选项中的陷阱"""
        traps = []
        
        for i, option in enumerate(options):
            # 检测绝对化表述
            absolute_words = ["必须", "一定", "绝对", "必然", "总是"]
            for word in absolute_words:
                if word in option:
                    traps.append({
                        "type": "绝对化表述",
                        "option_index": i,
                        "option": option[:50] + "..." if len(option) > 50 else option,
                        "word": word,
                        "severity": "high"
                    })
            
            # 检测反向表述
            if option.startswith("不") or option.startswith("非"):
                traps.append({
                    "type": "反向表述",
                    "option_index": i,
                    "option": option[:50] + "..." if len(option) > 50 else option,
                    "severity": "medium"
                })
        
        return traps
    
    def _generate_prevention_tips(
        self,
        question_traps: List[Dict],
        option_traps: List[Dict]
    ) -> List[str]:
        """生成预防建议"""
        tips = []
        
        if any(trap.get("type") == "绝对化表述" for trap in question_traps + option_traps):
            tips.append("注意绝对化表述，法律中很少有绝对的情况")
        
        if any(trap.get("type") == "反向提问" for trap in question_traps):
            tips.append("题目是反向提问，注意选择错误的选项")
        
        if any(trap.get("type") == "条件限定" for trap in question_traps):
            tips.append("注意条件限定，确保在正确的前提下分析")
        
        if any(trap.get("type") == "时间陷阱" for trap in question_traps):
            tips.append("注意时间顺序和期限，时间往往是关键因素")
        
        return tips if tips else ["仔细审题，注意细节"]
    
    async def _analyze_option_features(self, options: List[str]) -> Dict[str, Any]:
        """分析选项特征"""
        features = {
            "length_variance": self._calculate_length_variance(options),
            "common_words": self._find_common_words(options),
            "distinctive_words": self._find_distinctive_words(options),
            "negation_count": sum(1 for opt in options if "不" in opt or "非" in opt)
        }
        return features
    
    def _calculate_length_variance(self, options: List[str]) -> float:
        """计算选项长度方差"""
        if not options:
            return 0.0
        lengths = [len(opt) for opt in options]
        avg = sum(lengths) / len(lengths)
        variance = sum((l - avg) ** 2 for l in lengths) / len(lengths)
        return variance
    
    def _find_common_words(self, options: List[str]) -> List[str]:
        """找出选项中的共同词汇"""
        if not options:
            return []
        
        # 简单的共同词提取（实际可以使用更复杂的NLP方法）
        words = []
        for option in options:
            words.extend(option.split())
        
        from collections import Counter
        word_counts = Counter(words)
        common_words = [word for word, count in word_counts.items() if count >= len(options) * 0.5]
        return common_words[:5]  # 返回前5个
    
    def _find_distinctive_words(self, options: List[str]) -> Dict[int, List[str]]:
        """找出每个选项的独特词汇"""
        distinctive = {}
        for i, option in enumerate(options):
            option_words = set(option.split())
            other_words = set()
            for j, other_option in enumerate(options):
                if i != j:
                    other_words.update(other_option.split())
            distinctive[i] = list(option_words - other_words)[:3]  # 每个选项最多3个独特词
        return distinctive
    
    def _generate_exclusion_suggestions(
        self,
        options: List[str],
        similarity_analysis: Dict[str, Any],
        option_features: Dict[str, Any]
    ) -> List[Dict[str, Any]]:
        """生成排除建议"""
        suggestions = []
        
        # 基于相似度分析
        similar_pairs = similarity_analysis.get("similar_pairs", [])
        if similar_pairs:
            suggestions.append({
                "type": "相似选项排除",
                "description": f"检测到{len(similar_pairs)}对相似选项，可以重点对比这些选项",
                "pairs": similar_pairs
            })
        
        # 基于绝对化表述
        if option_features.get("negation_count", 0) > 0:
            suggestions.append({
                "type": "反向表述排除",
                "description": "部分选项包含反向表述，需要仔细判断"
            })
        
        return suggestions
    
    def _suggest_comparison_strategy(
        self,
        similarity_analysis: Dict[str, Any],
        option_features: Dict[str, Any]
    ) -> str:
        """建议对比策略"""
        similar_pairs = similarity_analysis.get("similar_pairs", [])
        if len(similar_pairs) > 0:
            return "建议使用对比法，重点对比相似选项的细微差异"
        else:
            return "选项差异较大，可以使用排除法逐个分析"
    
    def _determine_overall_strategy(
        self,
        structure: Dict[str, Any],
        traps: Dict[str, Any],
        option_analysis: Dict[str, Any]
    ) -> str:
        """确定整体策略"""
        risk_level = traps.get("summary", {}).get("risk_level", "low")
        question_type = structure.get("question_type", "未知")
        
        if risk_level == "high":
            return "高风险题目，建议仔细审题，逐步分析，注意陷阱"
        elif question_type == "案例题":
            return "案例题，建议先提取关键事实，再适用法律条文"
        elif question_type == "法条题":
            return "法条题，建议准确理解法条含义，注意法条的适用条件"
        else:
            return "常规题目，建议使用排除法和对比法结合"
    
    def _generate_step_by_step_strategy(
        self,
        structure: Dict[str, Any],
        traps: Dict[str, Any],
        option_analysis: Dict[str, Any]
    ) -> List[str]:
        """生成分步策略"""
        steps = []
        
        # 第一步：审题
        steps.append("1. 仔细阅读题目，识别关键词和陷阱")
        
        # 第二步：分析结构
        if structure.get("has_case"):
            steps.append("2. 提取案例中的关键事实（时间、主体、行为、结果）")
        if structure.get("has_provision"):
            steps.append("2. 识别相关法律条文，理解法条含义")
        
        # 第三步：分析选项
        similar_pairs = option_analysis.get("similarity_analysis", {}).get("similar_pairs", [])
        if similar_pairs:
            steps.append("3. 对比相似选项，找出细微差异")
        else:
            steps.append("3. 使用排除法，排除明显错误的选项")
        
        # 第四步：验证
        steps.append("4. 验证答案是否符合法律逻辑和题目要求")
        
        return steps
    
    def _suggest_time_management(
        self,
        difficulty: str,
        option_count: int
    ) -> Dict[str, Any]:
        """建议时间管理"""
        base_time = {
            "easy": 60,
            "medium": 120,
            "hard": 180
        }.get(difficulty, 120)
        
        # 根据选项数量调整
        time_per_option = 15
        total_time = base_time + (option_count * time_per_option)
        
        return {
            "suggested_time_seconds": total_time,
            "breakdown": {
                "审题": int(total_time * 0.3),
                "分析": int(total_time * 0.4),
                "选择": int(total_time * 0.2),
                "检查": int(total_time * 0.1)
            },
            "tips": [
                "如果超过建议时间，先标记，继续下一题",
                "完成所有题目后再回来检查标记的题目"
            ]
        }
    
    def _identify_common_mistakes(
        self,
        structure: Dict[str, Any],
        traps: Dict[str, Any]
    ) -> List[str]:
        """识别常见错误"""
        mistakes = []
        
        if any(trap.get("type") == "绝对化表述" for trap in traps.get("traps", [])):
            mistakes.append("容易被绝对化表述误导，选择过于绝对的选项")
        
        if any(trap.get("type") == "反向提问" for trap in traps.get("traps", [])):
            mistakes.append("容易忽略反向提问，选择正确的选项而非错误的选项")
        
        if structure.get("has_case") and structure.get("has_provision"):
            mistakes.append("容易混淆案例事实和法律条文，需要明确区分")
        
        return mistakes if mistakes else ["注意审题，避免粗心错误"]


# 单例实例
question_technique_service = QuestionTechniqueService()







